﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpLocalizer.Common;
using Microsoft.SharePoint;
using SpLocalizer.Common.DbApi;
using SpLocalizer.ContentSourceProviders.SpWeb;
using Microsoft.Practices.Unity;


namespace SpLocalizer.ContentSourceProviders
{
    /// <summary>
    /// Project for translation SharePoint metadata
    /// </summary>
    public class SpWebMetadataTranslationProject : AbstractTranslationProject, IDisposable
    {
        private SPSite _site = null;
        /// <summary>
        /// Local SharePoint Site project handle
        /// </summary>
        private SPSite Site
        {
            get
            {
                if (this._site == null)
                {
                    this._site = new SPSite(this.ConnectionString);        
                }
                return this._site;
            }
        }

        /// <summary>
        /// Open connection to the SharePoint web 
        /// </summary>
        /// <param name="ConnectionString">SharePoint web url</param>
        protected override void Bind(bool IncludeDescendants)  
        {            
            

            // By default bind tho the root web
            SpWebContent rootWeb = new SpWebContent();
            rootWeb.IncludeDescendants = IncludeDescendants;            
            this._ContentData.AddRange(rootWeb.Bind(this.Site.OpenWeb(), IncludeDescendants));
            

            if (string.IsNullOrEmpty(this.ProjectTitle))
            {
                this.ProjectTitle = rootWeb.ContentTitle;
            }

            
        }

        

        public void Dispose()
        {
            if (this._site != null)
            {
                this._site.Close();
                this._site = null;
            }

        }

        /// <summary>
        /// Register all content type provider types for conteainer
        /// </summary>
        /// <param name="RootContainer"></param>
        protected override void RegisterContentProviderTypes()
        {
            ServiceContainer.Container.RegisterType<AbstractSpContent, SpWebContent>(typeof(SpWebContent).Name);
            ServiceContainer.Container.RegisterType<AbstractSpContent, SpListContent>(typeof(SpListContent).Name);
            ServiceContainer.Container.RegisterType<BaseTranslationTask, SpUserResourceLocalizationTask>
                    (typeof(SpUserResourceLocalizationTask).Name);
                
        }


        protected override AbstractContent LoadContent(LocalizableContent content)
         {

             var SharePointContent = ServiceContainer.Resolve<AbstractSpContent>(content.ContentSourceProvider);
                //Restore other content properties
                SharePointContent.PropertiesSerializationXml = content.ContentSourceProviderData;
                SharePointContent.Id = content.Id;
                
                // If we have parent content - get it
                if (!string.IsNullOrEmpty(content.ParentContentId))
                {
                    SharePointContent.ParentContentId = content.ParentContentId;                    
                    var parentContent = this._ContentData.Where<AbstractContent>(prnt => SharePointContent.ParentContentId.Equals(prnt.ContentId))
                        .FirstOrDefault() as AbstractSpContent;

                    SharePointContent.ContentSource = parentContent.ContentSource;
                }
                // It's root content - put SPSite into content source
                else if (SharePointContent is SpWebContent)
                {
                    SharePointContent.ContentSource = this.Site;                    
                }

                /// If we have Content Id - try to bind with this
                if (!String.IsNullOrEmpty(content.ContentId))
                {
                    ((AbstractSpContent)SharePointContent).Bind(new Guid(content.ContentId), false);

                }/// If we have Content Address - try to bind with this
                else if (!String.IsNullOrEmpty(content.ContentAddress))
                {
                    ((AbstractSpContent)SharePointContent).Bind(content.ContentAddress, false);
                    /*throw new ArgumentException(String.Format("Content id's in content store {0} doesn't match content id in translaton store {1} for content address {3}",
                         AbstractContent.ContentId, content.ContentId, AbstractContent));*/
                }
                else
                {
                    throw new ArgumentException(String.Format("Content id in the translation database {0} doesn't have binding information",
                          content.Id));
                }            

                this._ContentData.Add(SharePointContent); 

                return SharePointContent;
        }
    }
}
